package cn.topcodes.tcsf.admin.service.impl;

import cn.topcode.unicorn.utils.StringUtil;
import cn.topcodes.tcsf.admin.domain.entity.EmailSendHistory;
import cn.topcodes.tcsf.admin.domain.form.EmailConfig;
import cn.topcodes.tcsf.admin.service.EmailService;
import cn.topcodes.tcsf.admin.service.SystemPropertyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.mail.internet.MimeMessage;
import java.util.Map;

/**
 * 邮件服务
 * @author Unicorn
 * @date 2017/12/23
 */
@Service
public class EmailServiceImpl implements EmailService {

    private static final String MAIL_HOST = "MAIL_HOST";

    private static final String MAIL_PORT = "MAIL_PORT";

    private static final String MAIL_USERNAME = "MAIL_USERNAME";

    private static final String MAIL_PASSWORD = "MAIL_PASSWORD";

    private static Logger logger = LoggerFactory.getLogger(EmailServiceImpl.class);

    @Autowired
    private SystemPropertyService systemPropertyService;

    @Autowired
    private EmailSendHistoryServiceImpl emailSendHistoryService;

    private JavaMailSender mailSender;

    @PostConstruct
    public void init() {
        start();
    }

    @PreDestroy
    public void destory() {
        stop();
    }

    /**
     * 发送测试邮件
     * @param emailConfig   测试邮件服务配置
     */
    @Override
    public void test(EmailConfig emailConfig) {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(emailConfig.getMailHost());
        mailSender.setPort(emailConfig.getMailPort());
        mailSender.setUsername(emailConfig.getUsername());
        mailSender.setPassword(emailConfig.getPassword());
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setSubject("测试邮件");
        mailMessage.setFrom(emailConfig.getUsername());
        mailMessage.setTo(emailConfig.getUsername());
        mailMessage.setText("您好！您看到这封邮件说明邮件服务已配置成功。");
        mailSender.send(mailMessage);
    }

    /**
     * 配置邮件服务
     * @param emailConfig
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void setEmailConfig(EmailConfig emailConfig) {
        if(emailConfig == null) {
            throw new IllegalArgumentException("请配置邮件服务");
        }
        Assert.hasText(emailConfig.getMailHost(), "请设置邮件服务器地址");
        Assert.notNull(emailConfig.getMailPort(), "请设置邮件服务器端口");
        Assert.hasText(emailConfig.getUsername(), "请设置邮件服务用户名");
        Assert.hasText(emailConfig.getPassword(), "请设置邮件服务密码");
        systemPropertyService.setSysProp(MAIL_HOST, emailConfig.getMailHost());
        systemPropertyService.setSysProp(MAIL_PORT, emailConfig.getMailPort() + "");
        systemPropertyService.setSysProp(MAIL_USERNAME, emailConfig.getUsername());
        systemPropertyService.setSysProp(MAIL_PASSWORD, emailConfig.getPassword());
        restart();
    }

    /**
     * 获取邮件服务配置
     * @return
     */
    @Override
    public EmailConfig getEmailConfig() {
        String mailHost = systemPropertyService.findSysProperty("MAIL_HOST", String.class, null);
        String portStr = systemPropertyService.findSysProperty("MAIL_PORT", String.class, null);
        Integer port = 25;
        if(StringUtil.isNotBlank(portStr)) {
            try {
                port = Integer.parseInt(portStr);
            }catch (Exception e) {}
        }
        String username = systemPropertyService.findSysProperty("MAIL_USERNAME", String.class, null);
        String password = systemPropertyService.findSysProperty("MAIL_PASSWORD", String.class, null);

        EmailConfig emailConfig = new EmailConfig();
        emailConfig.setMailHost(mailHost);
        emailConfig.setMailPort(port);
        emailConfig.setUsername(username);
        emailConfig.setPassword(password);
        return emailConfig;
    }

    public void start() {
        if(this.isEnabled()) {
            logger.info("邮件服务已启动");
            return;
        }

        EmailConfig emailConfig = getEmailConfig();
        if(StringUtil.isBlank(emailConfig.getMailHost()) ||
                emailConfig.getMailPort() != null ||
                StringUtil.isBlank(emailConfig.getUsername()) ||
                StringUtil.isBlank(emailConfig.getPassword())) {
            return ;
        }
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(emailConfig.getMailHost());
        mailSender.setPort(emailConfig.getMailPort());
        mailSender.setUsername(emailConfig.getUsername());
        mailSender.setPassword(emailConfig.getPassword());
        this.mailSender = mailSender;
    }

    public void stop() {
        this.mailSender = null;
    }

    public void restart() {
        stop();
        start();
    }

    /**
     * 发送
     * @param catalog     邮件类别
     * @param to          目标邮箱
     * @param subject     主题
     * @param isRichText  是否富文本
     * @param text        内容，支持富文本
     * @param resources   富文本内资源
     * @param attachments 附件列表
     */
    @Override
    public void send(String catalog, String from, String to, String subject, boolean isRichText, String text, Map<String, ClassPathResource> resources, Map<String, FileSystemResource> attachments) {
        if(!this.isEnabled()) {
            return;
        }

        EmailSendHistory history = new EmailSendHistory();
        history.setCatalog(catalog);
        history.setReceiver(to);
        history.setSubject(subject);
        history.setContent(text);

        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(text, isRichText);

            //  添加富文本资源
            if (resources != null) {
                for (Map.Entry<String, ClassPathResource> entry : resources.entrySet()) {
                    helper.addInline(entry.getKey(), entry.getValue());
                }
            }

            //  添加附件
            if (resources != null) {
                for (Map.Entry<String, FileSystemResource> entry : attachments.entrySet()) {
                    helper.addAttachment(entry.getKey(), entry.getValue());
                }
            }

            mailSender.send(message);
        }catch (Exception e) {
            history.setResult("失败:" + e.getMessage());
        }

        emailSendHistoryService.save(history);
    }

    /**
     * 是否可用
     * @return
     */
    @Override
    public boolean isEnabled() {
        return this.mailSender != null;
    }

}
